﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using Base.Core.Biz;
using NHibernate.Criterion;

namespace Library.Data.Hibernate
{
    public static class RepositoryHelper<T>
    {
        public static ICriteria CreateCriteria(ISession session, IList<SearchInfo> searchInfos, PagingInfo pagingInfo, IList<OrderInfo> orders)
        {
            ICriteria criteria = session.CreateCriteria(typeof(T));

            return CreateCriteria(criteria, searchInfos, pagingInfo, orders);
        }

        public static ICriteria CreateCriteria(ISession session, IList<SearchInfo> searchInfos, IList<OrderInfo> orders)
        {
            return CreateCriteria(session, searchInfos, null, orders);
        }

        public static ICriteria CreateCriteria(ISession session, IList<SearchInfo> searchInfos)
        {
            return CreateCriteria(session, searchInfos, null);
        }

        public static ICriteria CreateCriteria(ICriteria criteria, IList<SearchInfo> searchInfos, PagingInfo pagingInfo, IList<OrderInfo> orders)
        {
            return AddOrder(
                        AddPaging(
                            AddSearchInfo(criteria, searchInfos),
                            pagingInfo),
                        orders);
        }

        public static ICriteria AddSearchInfo(ICriteria criteria, IList<SearchInfo> searchInfos)
        {
            if (searchInfos != null && searchInfos.Count > 0)
            {
                foreach (var searchInfo in searchInfos)
                {
                    if (searchInfo.SearchOperator == SearchOperator.Equal)
                    {
                        criteria.Add(Expression.Eq(searchInfo.Name, searchInfo.Value));
                    }

                    if (searchInfo.SearchOperator == SearchOperator.Like)
                    {
                        criteria.Add(Expression.Like(searchInfo.Name, "%" + searchInfo.Value + "%"));
                    }
                    if (searchInfo.SearchOperator == SearchOperator.FromDate)
                    {                        
                        criteria.Add(Expression.Ge(searchInfo.Name, searchInfo.Value));
                    }
                    if (searchInfo.SearchOperator == SearchOperator.ToDate)
                    {
                        criteria.Add(Expression.Le(searchInfo.Name, searchInfo.Value));
                    }
                }
            }

            return criteria;
        }

        public static ICriteria AddOrder(ICriteria criteria, IList<OrderInfo> orders)
        {
            if (orders != null && orders.Count > 0)
            {
                foreach (var order in orders)
                {
                    if (order.OrderType == OrderType.Asc)
                    {
                        criteria.AddOrder(Order.Asc(order.Name));
                    }

                    if (order.OrderType == OrderType.Desc)
                    {
                        criteria.AddOrder(Order.Desc(order.Name));
                    }
                }
            }

            return criteria;
        }

        public static ICriteria AddPaging(ICriteria criteria, PagingInfo pagingInfo)
        {
            if (pagingInfo != null)
            {
                criteria.SetFirstResult((pagingInfo.PageIndex -1) * pagingInfo.RecordsPerPage);
                if (pagingInfo.RecordsPerPage != PagingInfo.AllRecordPerPage)
                {
                    criteria.SetMaxResults(pagingInfo.RecordsPerPage);
                }
            }

            return criteria;
        }
    }
}
